package com.ebupt.migu.music.popup.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ebupt.migu.globalpopup.entity.*;
import com.ebupt.migu.globalpopup.enums.FileTypeEnum;
import com.ebupt.migu.music.commons.constants.SysConstant;
import com.ebupt.migu.music.commons.utils.PathBuffer;
import com.ebupt.migu.music.popup.mapper.*;
import com.ebupt.migu.music.redis.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author tz
 */
@Slf4j
@Service
public class ActivityToRedis {

    @Resource
    private ActionInfoMapper actionInfoMapper;
    @Resource
    private ActivityInfoMapper activityInfoMapper;
    @Resource
    private ConditionRelationMapper conditionRelationMapper;
    @Resource
    private PageInfoMapper pageInfoMapper;
    @Resource
    private PopupInfoMapper popupInfoMapper;
    @Resource
    private AdsInfoMapper adsInfoMapper;
    @Autowired
    private RedisService redisService;

    /**
     * 前置条件属性编号：2-账号信息
     */
    private final static int TWO = 2;

    private static final int SEVEN = 7;
    private static final int EIGHT = 8;
    private static final int TWENTY_FOUR = 24;
    private static final int TWENTY_FIVE = 25;

    public void setActivityToRedis() {
        //查询符合入redis的活动信息
        List<ActivityInfo> activityInfos = activityInfoMapper.selectList(new QueryWrapper<ActivityInfo>().lambda()
                .eq(ActivityInfo::getActivityStatus, 4)
                .ne(ActivityInfo::getActivityType, 6));
        try {
            Set<Object> h5 = new HashSet<>();
            Set<Object> prim = new HashSet<>();
            if (null == activityInfos || activityInfos.size() < 1){
                log.info("没有可入库的活动信息");
            }else {
                for (ActivityInfo activity : activityInfos) {
                    //根据活动ID查询其他相关信息
                    ActivityRedisBean redisBean = getActivityRedisBean(activity);
                    //暂定key为 主键ID-活动ID
                    String redisKey = "popup-" + activity.getActivityId();
                    //写入redis
                    boolean flag = redisService.set(redisKey, JSON.toJSONString(redisBean));
                    if (flag) {
                        if (redisBean.getActivityInfo().getIsPrimary() == 0) {
                            prim.add(redisKey);
                        } else {
                            h5.add(redisKey);
                        }
                    }
                }
            }
            // 判断set集合key是否存在，求差集删除过期key
            if (redisService.exists(SysConstant.ACTIVITY_LIST_PRIM)){
                Set<Object> hasPrim = redisService.getSet(SysConstant.ACTIVITY_LIST_PRIM);
                hasPrim.removeAll(prim);
                hasPrim.forEach(e -> redisService.delete(e.toString()));
                redisService.setMembersDel(SysConstant.ACTIVITY_LIST_PRIM,hasPrim);
            }
            if (redisService.exists(SysConstant.ACTIVITY_LIST_H5)){
                Set<Object> hash5 = redisService.getSet(SysConstant.ACTIVITY_LIST_H5);
                hash5.removeAll(h5);
                hash5.forEach(e -> redisService.delete(e.toString()));
                redisService.setMembersDel(SysConstant.ACTIVITY_LIST_H5,hash5);
            }
            //更新活动id集合key
            if (prim.size() > 0){
                if (redisService.setSet(SysConstant.ACTIVITY_LIST_PRIM, prim)){
                    log.info("原生活动列表redis更新成功");
                }
            }
            if (h5.size() > 0){
                if (redisService.setSet(SysConstant.ACTIVITY_LIST_H5, h5)){
                    log.info("H5活动列表redis更新成功");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private ActivityRedisBean getActivityRedisBean(ActivityInfo activity){
        ActivityRedisBean redisBean = new ActivityRedisBean();
        redisBean.setActivityInfo(activity);
        redisBean.setActionInfo(actionInfoMapper.selectOne(new QueryWrapper<ActionInfo>().lambda()
                .eq(ActionInfo::getActivityId,activity.getActivityId())));
        redisBean.setPopupInfos(popupInfoMapper.selectList(new QueryWrapper<PopupInfo>().lambda()
                .eq(PopupInfo::getActivityId,activity.getActivityId())));
        redisBean.setConditionRelations(conditionRelationMapper.selectList(new QueryWrapper<ConditionRelation>().lambda()
                .eq(ConditionRelation::getActivityId,activity.getActivityId())));
        redisBean.setPageInfos(pageInfoMapper.selectList(new QueryWrapper<PageInfo>().lambda()
                .eq(PageInfo::getActivityId,activity.getActivityId())));
        return redisBean;
    }

    public void setAdsToRedis() {
        // 查询广告策略
        List<ActivityInfo> activityInfos = activityInfoMapper.selectList(new QueryWrapper<ActivityInfo>().lambda()
                .eq(ActivityInfo::getActivityStatus, 4)
                .eq(ActivityInfo::getActivityType, 6));
        Set<Object> ads = new HashSet<>();
        if (activityInfos.size() > 0) {
            List<AdsRedisBean> list = getAdsList(activityInfos);
            // 按广告场景进行分组
            Map<Integer, List<AdsRedisBean>> collect = list.stream().collect(Collectors.groupingBy(e -> e.getAdsInfo().getAdsScene()));
            collect.forEach((key, value) -> {
                //key ads-广告场景
                String redisKey = "ads-" + key;
                boolean flag = redisService.set(redisKey, JSON.toJSONString(value));
                if (flag) {
                    ads.add(redisKey);
                }
            });
        }
        // 判断set集合key是否存在，求差集删除过期key
        if (redisService.exists(SysConstant.ADS_LIST)){
            Set<Object> hasAds = redisService.getSet(SysConstant.ADS_LIST);
            hasAds.removeAll(ads);
            hasAds.forEach(e -> redisService.delete(e.toString()));
            redisService.setMembersDel(SysConstant.ADS_LIST,hasAds);
        }
        //更新活动id集合key
        if (ads.size() > 0){
            if (redisService.setSet(SysConstant.ADS_LIST, ads)){
                log.info("广告列表redis更新成功");
            }
        }
    }

    private List<AdsRedisBean> getAdsList(List<ActivityInfo> activityInfos){
        return activityInfos.stream().map(a -> new AdsRedisBean(a,
                adsInfoMapper.selectOne(new QueryWrapper<AdsInfo>().lambda()
                        .eq(AdsInfo::getActivityId,a.getActivityId())),
                conditionRelationMapper.selectList(new QueryWrapper<ConditionRelation>().lambda()
                        .eq(ConditionRelation::getActivityId,a.getActivityId())))).collect(Collectors.toList());
    }

    public void cleanDefunctActivity() {
        // 查询所有已结束的活动
        List<ActivityInfo> activityInfoList = activityInfoMapper.selectList(new QueryWrapper<ActivityInfo>()
                .lambda()
                .eq(ActivityInfo::getActivityStatus, 6));
        // 循环活动列表，解析每个活动
        activityInfoList.forEach(a -> {
            // 通过活动id查询条件配置表
            List<ConditionRelation> conditionRelationList = conditionRelationMapper.selectList(new QueryWrapper<ConditionRelation>()
                    .lambda()
                    .eq(ConditionRelation::getActivityId, a.getActivityId()));
            if (conditionRelationList == null || conditionRelationList.size() == 0) {
                log.info("当前无已结束的活动");
                return;
            }
            // 循环条件配置列表
            conditionRelationList.forEach(c -> {
                log.info("活动配置信息为：{}", c.toString());
                if (c.getPropertyCode().equals(TWO)) {
                    if (c.getRelation().equals(SEVEN) || c.getRelation().equals(EIGHT)) {
                        boolean isExists = redisService.exists(PathBuffer.NUMBERLOCATION.get("FILE_GLOBAL_PATH") + FileTypeEnum.FILE_TYPE_ENUM_TXT.getFile() + "/" + c.getConditionData());
//                        value = redisService.getSet("E:\\apps\\shared\\fine-operation-label\\upload\\crowd" + "/" + c.getConditionData());
                        keyBoolNull(a, isExists);
                    } else if (c.getRelation().equals(TWENTY_FOUR) || c.getRelation().equals(TWENTY_FIVE)) {
                        // 判断key是否存在
                        boolean isExists = redisService.exists(c.getConditionData());
                        keyBoolNull(a, isExists);
                    }
                }
            });
        });
    }

    /**
     * 判断redis中key的值是否为空
     *
     * @param a 活动信息
     * @param isExists 存在与否
     */
    private void keyBoolNull(ActivityInfo a, boolean isExists) {
        if (!isExists) {
            a.setActivityStatus(9);
            int i = activityInfoMapper.updateById(a);
            if (i > 0) {
                log.info("{}活动redis已失效，已修改活动状态", a.getActivityId());
            }
        } else {
            log.info("当前无待修改的活动");
        }
    }
}
